package com.micro.ai.template.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.micro.ai.commons.domain.ApiResponse;
import com.micro.ai.commons.exception.BusinessException;
import com.micro.ai.template.entity.Category;
import com.micro.ai.template.mapper.CategoryMapper;
import com.micro.ai.template.service.CategoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 分类服务实现类
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CategoryServiceImpl implements CategoryService {

    private final CategoryMapper categoryMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResponse<Category> createCategory(Category category) {
        log.info("创建分类: {}", category);
        
        // 验证分类名称是否重复
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Category::getName, category.getName());
        if (category.getParentId() != null) {
            wrapper.eq(Category::getParentId, category.getParentId());
        }
        if (categoryMapper.selectCount(wrapper) > 0) {
            throw new BusinessException("A0001", "同级分类名称已存在");
        }
        
        // 如果没有排序值，设置为最大值+1
        if (category.getSortOrder() == null) {
            LambdaQueryWrapper<Category> maxSortWrapper = new LambdaQueryWrapper<>();
            if (category.getParentId() != null) {
                maxSortWrapper.eq(Category::getParentId, category.getParentId());
            } else {
                maxSortWrapper.isNull(Category::getParentId);
            }
            maxSortWrapper.orderByDesc(Category::getSortOrder).last("LIMIT 1");
            Category maxSortCategory = categoryMapper.selectOne(maxSortWrapper);
            category.setSortOrder(maxSortCategory != null ? maxSortCategory.getSortOrder() + 1 : 0);
        }
        
        categoryMapper.insert(category);
        
        return ApiResponse.success(category);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResponse<Category> updateCategory(Category category) {
        log.info("更新分类: {}", category);
        
        // 验证分类是否存在
        Category existingCategory = categoryMapper.selectById(category.getId());
        if (existingCategory == null) {
            throw new BusinessException("A0002", "分类不存在");
        }
        
        // 验证分类名称是否重复（排除自己）
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Category::getName, category.getName())
               .ne(Category::getId, category.getId());
        if (category.getParentId() != null) {
            wrapper.eq(Category::getParentId, category.getParentId());
        }
        if (categoryMapper.selectCount(wrapper) > 0) {
            throw new BusinessException("A0001", "同级分类名称已存在");
        }
        
        categoryMapper.updateById(category);
        
        return ApiResponse.success(category);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResponse<Void> deleteCategory(Long categoryId) {
        log.info("删除分类: categoryId={}", categoryId);
        
        // 验证分类是否存在
        Category category = categoryMapper.selectById(categoryId);
        if (category == null) {
            throw new BusinessException("A0002", "分类不存在");
        }
        
        // 检查是否有子分类
        LambdaQueryWrapper<Category> childWrapper = new LambdaQueryWrapper<>();
        childWrapper.eq(Category::getParentId, categoryId);
        if (categoryMapper.selectCount(childWrapper) > 0) {
            throw new BusinessException("A0003", "该分类下有子分类，无法删除");
        }
        
        // TODO: 检查分类下是否有模板
        
        categoryMapper.deleteById(categoryId);
        
        return ApiResponse.<Void>success(null);
    }

    @Override
    public ApiResponse<Category> getCategoryById(Long categoryId) {
        log.info("查询分类: categoryId={}", categoryId);
        
        Category category = categoryMapper.selectById(categoryId);
        if (category == null) {
            throw new BusinessException("A0002", "分类不存在");
        }
        
        return ApiResponse.success(category);
    }

    @Override
    public ApiResponse<List<Category>> getCategoryTree() {
        log.info("查询分类树");
        
        // 查询所有分类
        List<Category> allCategories = categoryMapper.selectList(null);
        
        // 构建树形结构
        List<Category> tree = buildCategoryTree(allCategories, null);
        
        return ApiResponse.success(tree);
    }

    @Override
    public ApiResponse<List<Category>> getCategoriesByParentId(Long parentId) {
        log.info("查询子分类: parentId={}", parentId);
        
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        if (parentId != null) {
            wrapper.eq(Category::getParentId, parentId);
        } else {
            wrapper.isNull(Category::getParentId);
        }
        wrapper.orderByAsc(Category::getSortOrder);
        
        List<Category> categories = categoryMapper.selectList(wrapper);
        
        return ApiResponse.success(categories);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResponse<Void> moveCategory(Long categoryId, Long newParentId) {
        log.info("移动分类: categoryId={}, newParentId={}", categoryId, newParentId);
        
        // 验证分类是否存在
        Category category = categoryMapper.selectById(categoryId);
        if (category == null) {
            throw new BusinessException("A0002", "分类不存在");
        }
        
        // 验证不能移动到自己或自己的子分类下
        if (newParentId != null && categoryId.equals(newParentId)) {
            throw new BusinessException("A0001", "不能移动到自己下面");
        }
        
        // 验证新父分类是否存在
        if (newParentId != null) {
            Category newParent = categoryMapper.selectById(newParentId);
            if (newParent == null) {
                throw new BusinessException("A0002", "目标父分类不存在");
            }
            
            // 检查是否会形成循环引用
            if (isDescendant(categoryId, newParentId)) {
                throw new BusinessException("A0001", "不能移动到自己的子分类下");
            }
        }
        
        category.setParentId(newParentId);
        categoryMapper.updateById(category);
        
        return ApiResponse.<Void>success(null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResponse<Void> updateCategorySort(Long categoryId, Integer sortOrder) {
        log.info("更新分类排序: categoryId={}, sortOrder={}", categoryId, sortOrder);
        
        // 验证分类是否存在
        Category category = categoryMapper.selectById(categoryId);
        if (category == null) {
            throw new BusinessException("A0002", "分类不存在");
        }
        
        category.setSortOrder(sortOrder);
        categoryMapper.updateById(category);
        
        return ApiResponse.<Void>success(null);
    }

    /**
     * 构建分类树
     */
    private List<Category> buildCategoryTree(List<Category> allCategories, Long parentId) {
        List<Category> result = new ArrayList<>();
        
        // 按 parentId 分组
        Map<Long, List<Category>> categoryMap = allCategories.stream()
            .collect(Collectors.groupingBy(
                category -> category.getParentId() != null ? category.getParentId() : -1L
            ));
        
        // 获取指定 parentId 的分类
        List<Category> categories = parentId != null 
            ? categoryMap.getOrDefault(parentId, new ArrayList<>())
            : categoryMap.getOrDefault(-1L, new ArrayList<>());
        
        // 按排序值排序
        categories.sort((c1, c2) -> {
            Integer sort1 = c1.getSortOrder() != null ? c1.getSortOrder() : 0;
            Integer sort2 = c2.getSortOrder() != null ? c2.getSortOrder() : 0;
            return sort1.compareTo(sort2);
        });
        
        // 递归构建子树
        for (Category category : categories) {
            List<Category> children = buildCategoryTree(allCategories, category.getId());
            // 设置子分类列表
            if (!children.isEmpty()) {
                category.setChildren(children);
            }
            result.add(category);
        }
        
        return result;
    }

    /**
     * 检查 targetId 是否是 categoryId 的后代
     */
    private boolean isDescendant(Long categoryId, Long targetId) {
        if (categoryId == null || targetId == null) {
            return false;
        }
        
        Category target = categoryMapper.selectById(targetId);
        while (target != null && target.getParentId() != null) {
            if (target.getParentId().equals(categoryId)) {
                return true;
            }
            target = categoryMapper.selectById(target.getParentId());
        }
        
        return false;
    }
}

